#include "thread.hpp"
#include "LockGuard.hpp"

using namespace std;

string GetThreadname()
{
    static int number = 1;
    char name[64];
    snprintf(name, sizeof(name), "thread_%d", number++);
    return name;
}

void Print()
{
    while(1)
    {
        cout << "hello, hello, hello" << endl;
        sleep(1);
    }
}

// class ThreadData
// {
// public:
//     ThreadData(const string &threadname, pthread_mutex_t *pmutex)
//         :_threadname(threadname)
//         ,_pmutex(pmutex)
//     {}
// public:
//     string _threadname;
//     pthread_mutex_t *_pmutex;
// };

// int ticket = 10000;
// // pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 

// void GetTicket(ThreadData *td)
// {
//     while(1)
//     {
//         LockGuard lockguard(td->_pmutex);
//         if(ticket > 0)
//         {
//             // 模拟抢票时间
//             usleep(1000);
//             printf("%s get a ticket: %d\n", td->_threadname.c_str(), ticket);
//             ticket--;
//             //pthread_mutex_unlock(mutex);
//         }
//         else{
//             //pthread_mutex_unlock(mutex);
//             break;
//         }
//     }
// }

// int main()
// {
//     pthread_mutex_t mutex;
//     pthread_mutex_init(&mutex, nullptr) ;

//     string name1 = GetThreadname();
//     ThreadData *td1 = new ThreadData(name1, &mutex);
//     Thread<ThreadData *> t1(GetTicket, name1, td1);

//     string name2 = GetThreadname();
//     ThreadData *td2 = new ThreadData(name2, &mutex);
//     Thread<ThreadData *> t2(GetTicket, name2, td2);

//     string name3 = GetThreadname();
//     ThreadData *td3 = new ThreadData(name3, &mutex);
//     Thread<ThreadData *> t3(GetTicket, name3, td3);

//     string name4 = GetThreadname();
//     ThreadData *td4 = new ThreadData(name4, &mutex);
//     Thread<ThreadData *> t4(GetTicket, name4, td4);

    
//     t2.Start();
//     t3.Start();
//     t4.Start();

//     t1.Join();
//     t2.Join();
//     t3.Join();
//     t4.Join();

//     pthread_mutex_destroy(&mutex);

//     return 0;
// }

// int main()
// {
//     Thread t(Print, GetThreadname());
//     cout << "Is running? -> : " << t.IsRunning() << endl;
//     t.Start();
//     cout << "Is running? -> : " << t.IsRunning() << endl;

//     t.Join();

//     return 0;
// }

// int ticket = 10000;
// pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 静态分配

// void *route(void *arg)
// {
// 	char *id = (char*)arg;
// 	while ( 1 ) 
// 	{
// 		pthread_mutex_lock(&mutex); // 加锁
// 		if ( ticket > 0 ) 
// 		{
// 			usleep(1000);
// 			printf("%s get a ticket: %d\n", id, ticket);
// 			ticket--;
// 			pthread_mutex_lock(&mutex); // 解锁
// 		} 		
// 		else 
// 		{
// 			pthread_mutex_lock(&mutex); // 解锁
// 			break;
// 		}
// 	}
// } 
// int main( void )
// {
// 	pthread_t t1, t2, t3, t4;
	
// 	pthread_create(&t1, NULL, route, (void *)"thread 1");
// 	pthread_create(&t2, NULL, route, (void *)"thread 2");
// 	pthread_create(&t3, NULL, route, (void *)"thread 3");
// 	pthread_create(&t4, NULL, route, (void *)"thread 4");
	
// 	pthread_join(t1, NULL);
// 	pthread_join(t2, NULL);
// 	pthread_join(t3, NULL);
// 	pthread_join(t4, NULL);
	
// 	return 0;
// }

pthread_cond_t cond;
pthread_mutex_t mutex;
void *r1( void *arg )
{
	while ( 1 )
	{
		pthread_cond_wait(&cond, &mutex);
		printf("活动\n");
	}
} 
void *r2(void *arg )
{
	while ( 1 ) 
	{
		pthread_cond_signal(&cond);
		sleep(1);
	}
} 

int main( void )
{
	pthread_t t1, t2;
	pthread_cond_init(&cond, NULL);
	pthread_mutex_init(&mutex, NULL);
	
	pthread_create(&t1, NULL, r1, NULL);
	pthread_create(&t2, NULL, r2, NULL);
	
	pthread_join(t1, NULL);
	pthread_join(t2, NULL);
	
	pthread_mutex_destroy(&mutex);
	pthread_cond_destroy(&cond);
	
	return 0;
}